package com.pearadmin.nucleus.shiro.realm;

import com.pearadmin.system.domain.SysPower;
import com.pearadmin.system.domain.SysRole;
import com.pearadmin.system.domain.SysUser;
import com.pearadmin.system.mapper.SysPowerMapper;
import com.pearadmin.system.mapper.SysRoleMapper;
import com.pearadmin.system.mapper.SysUserMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import javax.security.auth.login.AccountLockedException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @title:权限处理
 * @descible:自定义权限处理与登陆认证
 * @author:就眠仪式
 * @createTime:2019年12月5日
 * */
public class ShiroRealm extends AuthorizingRealm {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysPowerMapper sysPowerMapper;

    /**
     * 认证处理
     * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        String userName = (String) principalCollection.getPrimaryPrincipal();
        Set<String> roles = new HashSet<>();
        Set<String> permissions = new HashSet<>();

        for (SysRole sysRole:sysRoleMapper.selectRoleByUsername(userName)) {
            roles.add(sysRole.getCode());
            for (SysPower sysPower:sysPowerMapper.selectPowerByRoleId(sysRole.getId())) {
                permissions.add(sysPower.getCode());
            }
        }
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addStringPermissions(permissions);
        authorizationInfo.addRoles(roles);
        return authorizationInfo;
    }

    /**
     * 登陆处理
     * */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //从token获取用户名,从主题传过来的认证信息中获取
        //加这一步的目的是在Post请求时会先进入认证然后再到请求
        if(authenticationToken.getPrincipal()==null){
            return null;
        }
        //获取用户登陆信息,用户名称
        String userName = authenticationToken.getPrincipal().toString();
        String password = new String((char[])authenticationToken.getCredentials());

        //根据Service 调用用户名,查找用户的全部信息
        SysUser user =  sysUserMapper.selectUserByUsername(userName);

        if(user==null){

            throw new UnknownAccountException("账户不存在");

        }else if(user.getStatus().equals("1")){

            throw new LockedAccountException("账户已经被锁定");

        }else{
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName,user.getPassword(),getName());
            return simpleAuthenticationInfo;
        }
    }
}
